require 'test_helper'


class ClientsControllerTest < ActionController::TestCase
  setup do
    @client_a = clients  :ircclient_a
    @client_b = clients  :simclient_a
    @last_msg = messages :simclient_user_c_message
    @room_b   = rooms    :room_b
    @name     = @client_a.name
    @secret   = @client_a.secret
    @room     = @client_a.room
  end

  def post_client client_params
    post :create , :client => client_params
  end

  def post_message client_name , client_secret , message_params
    post :message , :client => { :secret => client_secret } , :name => client_name , :message => message_params
  end


  ## client creation tests ##

  test "should not create client with missing channel name" do
    assert_no_difference('Client.count') { post_client CLIENT_PARAMS_MISSING_NAME }
    assert_response 420
  end

  test "should not create client with empty channel name" do
    assert_no_difference('Client.count') { post_client CLIENT_PARAMS_EMPTY_NAME   }
    assert_response 420
  end

  test "should not create client with missing client type" do
    assert_no_difference('Client.count') { post_client CLIENT_PARAMS_MISSING_TYPE }
    assert_response 420
  end

  test "should not create client with empty client type" do
    assert_no_difference('Client.count') { post_client CLIENT_PARAMS_EMPTY_TYPE   }
    assert_response 420
  end

  test "should create client with valid params" do
    assert_difference('Client.count')    { post_client CLIENT_C_PARAMS_VALID      }
    assert_not_equal DUPLICATE_CLIENT_SECRET , (JSON.parse response.body)['secret']
    assert_not_nil assigns :client
    assert_response        :success
  end

  test "should not create client with duplicate channel name" do
    assert_no_difference('Client.count') { post_client CLIENT_A_PARAMS_VALID      }
    assert_equal DUPLICATE_CLIENT_SECRET , (JSON.parse response.body)['secret'     ]
    assert_equal ROOM_A_SECRET           , (JSON.parse response.body)['room_secret']
    assert_nil assigns :client
    assert_response    :success
  end


  ## rooms fetch tests ##

  test "should not fetch rooms with missing client secret" do
    post :rooms , :client => {                     } , :name => @name
    assert_response :unauthorized
  end

  test "should not fetch rooms with unknown channel name" do
    post :rooms , :client => { :secret => @secret  } , :name => 'name'
    assert_response :unauthorized
  end

  test "should not fetch rooms with empty client secret" do
    post :rooms , :client => { :secret => ''       } , :name => @name
    assert_response :unauthorized
  end

  test "should not fetch rooms with incorrect client secret" do
    post :rooms , :client => { :secret => 'secret' } , :name => @name
    assert_response :unauthorized
  end

  test "should fetch other public rooms with valid params" do
    post :rooms , :client => { :secret => @secret  } , :name => @name
    assert_equal     1              , (JSON.parse response.body)['rooms'].size
    assert_not_equal @room  .secret , (JSON.parse response.body)['rooms'][0]['secret']
    assert_equal     @room_b.secret , (JSON.parse response.body)['rooms'][0]['secret']
    assert_response  :success
  end


  ## room bridging tests ##

  test "should bridge rooms with valid secret and room secret" do
    assert_difference('Room.count' , -1) do
      post :bridge , :client => { :secret => @secret } , :name => @name , :room_secret => ROOM_B_SECRET
    end
    assert_equal           @room_b.secret , (JSON.parse response.body)['room_secret']
    assert_not_nil assigns :client
    assert_response        :success
  end


  ## message creation tests ##

  test "should not create message with missing nick" do
    assert_no_difference('Message.count') { post_message @name  , @secret  , MESSAGE_PARAMS_MISSING_NICK }
    assert_response 420
  end

  test "should not create message with empty nick" do
    assert_no_difference('Message.count') { post_message @name  , @secret  , MESSAGE_PARAMS_EMPTY_NICK   }
    assert_response 420
  end

  test "should not create message with missing text" do
    assert_no_difference('Message.count') { post_message @name  , @secret  , MESSAGE_PARAMS_MISSING_TEXT }
    assert_response 420
  end

  test "should not create message with empty text" do
    assert_no_difference('Message.count') { post_message @name  , @secret  , MESSAGE_PARAMS_EMPTY_TEXT   }
    assert_response 420
  end

  test "should not create message with unknown channel name" do
    assert_no_difference('Message.count') { post_message 'name' , @secret  , MESSAGE_PARAMS_VALID        }
    assert_response :unauthorized
  end

  test "should not create message with incorrect client secret" do
    assert_no_difference('Message.count') { post_message @name  , 'secret' , MESSAGE_PARAMS_VALID        }
    assert_response :unauthorized
  end

  test "should create message with valid params" do
    post_message @name , @secret  , MESSAGE_PARAMS_VALID
      assert_response :success
  end


  ## messages fetch tests ##

  test "should not fetch messages with unknown channel name" do
    post :messages , :client => { :secret => @secret  } , :name => 'name' , :last_id => 1
    assert_response :unauthorized
  end

  test "should not fetch messages with missing client secret" do
    post :messages , :client => {                     } , :name => @name , :last_id => 1
    assert_response :unauthorized
  end

  test "should not fetch messages with empty client secret" do
    post :messages , :client => { :secret => ''       } , :name => @name , :last_id => 1
    assert_response :unauthorized
  end

  test "should not fetch messages with incorrect client secret" do
    post :messages , :client => { :secret => 'secret' } , :name => @name , :last_id => 1
    assert_response :unauthorized
  end

  test "should fetch all messages with missing last message id" do
    post :messages , :client => { :secret => @secret  } , :name => @name
    assert_response 420
  end

  test "should fetch all messages with empty last message id" do
    post :messages , :client => { :secret => @secret  } , :name => @name , :last_id => ''
    assert_response 420
  end

  test "should fetch all messages with valid params and floor id" do
    post :messages , :client => { :secret => @secret  } , :name => @name , :last_id => 0
    assert_equal N_MESSAGES_QUEUED + 4 , (JSON.parse response.body)['messages'].size
    assert_response :success
  end

  test "should fetch last message with valid params and last message id - 1" do
    post :messages , :client => { :secret => @secret  } , :name => @name , :last_id => @last_msg.id - 1
    assert_equal 1                     , (JSON.parse response.body)['messages'].size
    assert_response :success
  end

  test "should fetch zero messages with valid params and last message id" do
    post :messages , :client => { :secret => @secret  } , :name => @name , :last_id => @last_msg.id
    assert_equal 0                     , (JSON.parse response.body)['messages'].size
    assert_response :success
  end
end
